package edu.bucknell.edash;


import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.text.format.DateFormat;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.ToggleButton;




public class EdashMain extends FragmentActivity{
	
	private static final String FIRST_LINE = "TIME, MAIN VOLTAGE (V), MAIN CURRENT (A), AUX VOLTAGE (V), AUX CURRENT(A), SPEED (MPH), TEMPERATURE BATTERY (F), TEMPERATURE AMBIENT (F), CHARGE REMOVED (AMP-HOURS)\n";
	/**
	 * Enumerated Type for data handler message indices
	 */
	public class measurementsEnum{
		public static final int MAIN_VOLTAGE = 0;
		public static final int MAIN_CURRENT = 1;
		public static final int AUX_VOLTAGE = 2;
		public static final int AUX_CURRENT = 3;
		public static final int SPEED =4;
		public static final int BATTERY_TEMP=5;
		public static final int AMBIENT_TEMP =6;
		public static final int CHARGE_REMOVED =7;
		public static final int SCALE = 8;
	}
	
	/**
	 * Declaring the swipe interface
	 */
	private ViewPager _mViewPager;
	private ViewPagerAdapter _adapter;
	
	/**
	 * Declaring the storage variables
	 */
	private float mainVoltage, mainCurrent, auxVoltage, auxCurrent, speed, batteryTemp, ambientTemp =0;
	private String fileName = "";

	/**
	 * public GUI elements to be initialized by the seperate fragments (screens)
	 */
	public Gauge gMainVoltage;
	public Gauge gMainCurrent;
	public Gauge gChargeRemoved;
	public Gauge gAuxVoltage;
	public Gauge gAuxCurrent;
	public Gauge gSpeed;
	public TextView tAmbientTemp;
	public TextView tBatteryTemp;
	public TextView tChargeRemaining;
	public TextView tAuxMeasurements;
	public ImageView iWarning;
	public float chargeRemoved = 0;
	public FileOutputStream outputFile= null;
	public ToggleButton logButton;
	
	/**
	 * Handler for IOIO communication
	 */
	public static Handler _handler;
	
	/**
	 * Time so we can calculate time difference and have a time stamp for the log file
	 */
	public long oldTime = System.currentTimeMillis();
	

	/** Called when the activity is first created. */
	@SuppressLint("HandlerLeak")
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_edash_main);
		setUpView();
		setTab();
		
		
		/**
		 * What the handler should do when receiving a message
		 */
		_handler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				
				Bundle tempBundle = msg.getData();
				double array[] = tempBundle.getDoubleArray("1");
				/**
				 * Copy elements from the message array into the local varaibles
				 * Set the GUI elements to those values
				 */
				mainCurrent = (float) array[measurementsEnum.MAIN_CURRENT];
				gMainCurrent.setTargetVal(mainCurrent);
				mainCurrent = roundNDecimalPlaces(mainCurrent,0);
				
				mainVoltage = (float)array[measurementsEnum.MAIN_VOLTAGE];
				gMainVoltage.setTargetVal(mainVoltage);
				mainVoltage = roundNDecimalPlaces(mainVoltage,0);
				
				auxVoltage = (float)array[measurementsEnum.AUX_VOLTAGE];
				gAuxVoltage.setTargetVal(auxVoltage);
				auxVoltage = roundNDecimalPlaces(auxVoltage,1);
				
				auxCurrent = (float)array[measurementsEnum.AUX_CURRENT];
				gAuxCurrent.setTargetVal(auxCurrent);
				auxCurrent = roundNDecimalPlaces(auxCurrent,1);
				
				speed = (float)array[measurementsEnum.SPEED];
				gSpeed.setTargetVal(speed);
				speed = roundNDecimalPlaces(speed,0);
				
				ambientTemp = roundNDecimalPlaces(array[measurementsEnum.AMBIENT_TEMP],1);
				tAmbientTemp.setText("Ambient Temp:\t" + (int)ambientTemp);
				
				batteryTemp = roundNDecimalPlaces(array[measurementsEnum.BATTERY_TEMP],1);
				tBatteryTemp.setText("Battery Temp:\t\t" + (int)batteryTemp);
				
				float scale = roundNDecimalPlaces(array[measurementsEnum.SCALE],4);
				System.out.println("Scale: " + scale);
				
				chargeRemoved+=(float)array[measurementsEnum.CHARGE_REMOVED];
				gChargeRemoved.setTargetVal(chargeRemoved);
				
				/**
				 * Check to see if the voltage is below 10 Volts in order to display the low battery warning
				 */
				if(auxVoltage<10){
					iWarning.setVisibility(View.VISIBLE);
				}else
					iWarning.setVisibility(View.INVISIBLE);
				
				tChargeRemaining.setText(""+roundNDecimalPlaces(gChargeRemoved.getMaxVal()-chargeRemoved,2) + " Amp-Hours");
				
				long newTime = System.currentTimeMillis();
				oldTime = newTime;
				
				if(logButton.isChecked())
					updateLogFile();

				super.handleMessage(msg);
			}

		};
		
		/**
		 * When the main activity is started it will start the IOIO service
		 */
		startService(new Intent(this, EdashIOIOService.class));


	}



	@Override
	protected void onResume() {
		super.onResume();

	
	}

	
	@Override
	protected void onPause() {
		System.out.println("on pause");
		super.onPause();

	}

	/**
	 * Setting up Fragment views
	 */
	private void setUpView(){    	
		_mViewPager = (ViewPager) findViewById(R.id.viewPager);

		_adapter = new ViewPagerAdapter(getApplicationContext(),getSupportFragmentManager());
		_adapter.notifyDataSetChanged();
		_mViewPager.setAdapter(_adapter);
		_mViewPager.setCurrentItem(0);

	}
	
	/**
	 * Setting up the tabbed layout
	 */
	private void setTab(){
		_mViewPager.setOnPageChangeListener(new OnPageChangeListener(){

			@Override
			public void onPageScrollStateChanged(int position) {}
			@Override
			public void onPageScrolled(int arg0, float arg1, int arg2) {}
			@Override
			public void onPageSelected(int position) {
				// TODO Auto-generated method stub
				switch(position){
				case 0:
					findViewById(R.id.first_tab).setVisibility(View.VISIBLE);
					findViewById(R.id.second_tab).setVisibility(View.INVISIBLE);
					break;

				case 1:
					findViewById(R.id.first_tab).setVisibility(View.INVISIBLE);
					findViewById(R.id.second_tab).setVisibility(View.VISIBLE);
					break;
				}
			}

		});

	}


	/**
	 * Round a double to n decimal places
	 * @param value
	 * @param n
	 * @return 
	 */
	private float roundNDecimalPlaces(final double value, int n){
		double factor = Math.pow(10.0, n);
		double ret = Math.round(value*factor)/factor;
		return (float) ret;

	}
	
	/**
	 * Create a log file with a new name using a time stamp as the file name
	 */
	public void createFile() {
		int fileCount = 0;
		File root = Environment.getExternalStorageDirectory();
		Date now = new Date();
		fileName = "edash_log_" + DateFormat.format("yyyy_MM_dd", now).toString();
		File f = new File(root, fileName+"_"+fileCount+".csv");

		while(f.exists()){
			fileCount++;
			f = new File(root,  fileName+"_"+fileCount+".csv");

		}


		try {
			outputFile = new FileOutputStream(new File( root,  fileName+"_"+fileCount+".csv"), true);
			outputFile.write(FIRST_LINE.getBytes());
		} catch (FileNotFoundException e) {
			System.out.println(e.getStackTrace());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Place all of the data in local variables into the log file with a time stamp
	 */
	@SuppressLint("SimpleDateFormat")
	private void updateLogFile(){
		if(outputFile == null)
			createFile();
		Date now = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss:SSS");
		String time = sdf.format(now);

		String line = ""+time+" , %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f\n"; 
		line = String.format(line,mainVoltage, mainCurrent, auxVoltage, auxCurrent, speed, batteryTemp, ambientTemp, chargeRemoved);
		try {
			outputFile.write(line.getBytes());
		} catch (IOException e) {
			createFile();
			updateLogFile();
			e.printStackTrace();
		}

	}
	



}
